﻿using Azure;
using Azure.AI.OpenAI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Microsoft.SemanticKernel.Memory;
using Microsoft.SemanticKernel.Planning.Handlebars;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static System.Net.Mime.MediaTypeNames;
using Path = System.IO.Path;


namespace SemanticKernel
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                await PlannerTest();
                //Task task = OutMessageAsync();
                return;
            }
            catch (Exception ex)
            {

                throw;
            }

        }
        /// <summary>
        /// 链接gpt，输出回应消息
        /// </summary>
        public void OutMessage()
        {
            //string endpoint = "https://openaikeyaskition.openai.azure.com/";
            //string key = "75db2e6ae11d4349910dce3a7b265282";
            //AzureOpenAIClient client = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(key));
            //OpenAI.Chat.ChatClient chatClient = client.GetChatClient("gpt-4o-mini");
            //List<ChatMessage> chatMessages = new List<ChatMessage>();
            //UserChatMessage userChatMessage = ChatMessage.CreateUserMessage(Input.Text);
            //chatMessages.Add(userChatMessage);
            //System.ClientModel.ClientResult<ChatCompletion> clientResult = chatClient.CompleteChat(chatMessages);
            //string text = clientResult.Value.Content[0].Text;
            //TextBox textBox = new TextBox();
            //textBox.Text = text;
            //textBox.Width = right.ActualWidth;
            //listBox.Items.Add(textBox);
        }
        /// <summary>
        /// 链接gpt，输出回应消息-异步
        /// </summary>
        /// <returns></returns>
        public async Task OutMessageAsync()
        {//Azure.AI.OpenAI, 2.0.0-beta.2

            //TextBox textBox2 = new TextBox();
            //textBox2.Width = right.ActualWidth;
            //listBox.Items.Add(textBox2);
            //string msg = "";
            //string endpoint = "https://openaikeyaskition.openai.azure.com/";
            //string key = "75db2e6ae11d4349910dce3a7b265282";
            //AzureOpenAIClient client = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(key));
            //OpenAI.Chat.ChatClient chatClient = client.GetChatClient("gpt-4o-mini");
            //List<ChatMessage> chatMessages = new List<ChatMessage>();
            //UserChatMessage userChatMessage = ChatMessage.CreateUserMessage(Input.Text);
            //chatMessages.Add(userChatMessage);
            //System.ClientModel.AsyncResultCollection<StreamingChatCompletionUpdate> asyncResultCollection = chatClient.CompleteChatStreamingAsync(chatMessages);
            //await using (var asyncEnumerator = asyncResultCollection.GetAsyncEnumerator())
            //{
            //    while (await asyncEnumerator.MoveNextAsync().ConfigureAwait(false))
            //    {
            //        StreamingChatCompletionUpdate update = asyncEnumerator.Current;
            //        if (update.ContentUpdate.Count == 0)
            //        {
            //            continue;
            //        }
            //        string text = update.ContentUpdate.First().Text;
            //        msg += text;
            //        // 非UI线程调用的  
            //        System.Windows.Application.Current.Dispatcher.Invoke(() =>
            //        {
            //            // 更新UI的代码  
            //            textBox2.Text = msg;
            //        });
            //        Thread.Sleep(10);
            //    }
            //}
        }

        /// <summary>
        /// 完成翻译
        /// </summary>
        public async Task TranslateAsync()
        {
            object msg = "Old";
            List<object> list = new List<object>() { msg };
            Tess(out msg,list);
            //Settings settings = new Settings();
            //IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
            //Kernel kernel = kernelBuilder.AddAzureOpenAIChatCompletion(settings.AOAIModel, settings.AOAIEndpoint, settings.AOAIKey).Build();
            //string currentDirectory = Directory.GetCurrentDirectory();
            //KernelPlugin? plugin = kernel.CreatePluginFromPromptDirectory(System.IO.Path.Combine(currentDirectory, "TranslatePlugin"));

            //FunctionResult? transalteContent = await kernel.InvokeAsync(plugin["Basic"], new() { ["input"] = Input.Text });
            //string? text = transalteContent.GetValue<string>();
            //TextBox textBox = new TextBox();
            //textBox.Text = text;
            //textBox.Width = right.ActualWidth;
            //listBox.Items.Add(textBox);
        }

        public void Tess(out object msg, List<object> list)
        {
            msg = "new";
        }

        public async Task PluginsTestAsync()
        {
            Settings settings = new Settings();
            IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
            Kernel kernel = kernelBuilder.AddAzureOpenAIChatCompletion(settings.AOAIModel, settings.AOAIEndpoint, settings.AOAIKey).Build();
/*            string promptTemplate = @"System: You are a python developer 。 User:{{$input}}";
            var codeFunction = kernel.CreateFunctionFromPrompt(promptTemplate, new OpenAIPromptExecutionSettings() { MaxTokens = 2000, Temperature = 0.2, TopP = 0.5 });
            var result = await kernel.InvokeAsync(codeFunction, new() { ["input"] = "Generate a bubble algorithm method with python" });
            string? v = result.GetValue<string>();
            var pluginDirectory = System.IO.Path.Combine("../../..", "plugins");
            var translate_plugin = kernel.CreatePluginFromPromptDirectory(System.IO.Path.Combine(pluginDirectory, "TranslatePlugin"));
            var transalteContent = await kernel.InvokeAsync(translate_plugin["MultiLanguage"], new() { ["input"] = "hello", ["language"] = "fr" });
            string? v1 = transalteContent.GetValue<string>();*/

            //#!import ../../../Plugins/CustomPlugin/CompanySearchPlugin.cs
            var companySearchPluginObj = new CompanySearchPlugin();
            var companySearchPlugin = kernel.ImportPluginFromObject(companySearchPluginObj, "CompanySearchPlugin");
            var searchContent = await kernel.InvokeAsync(companySearchPlugin["EmployeeSearch"], new() { ["input"] = "HR" });
            string? v2 = searchContent.GetValue<string>();
            var weatherContent = await kernel.InvokeAsync(companySearchPlugin["WeatherSearch"], new() { ["city"] = "Guangzhou" });
            string? v3 = weatherContent.GetValue<string>();
        }

        public async Task PlannerTest()
        {
            Settings settings = new Settings();
            Kernel kernel = Kernel.CreateBuilder()
                .AddAzureOpenAIChatCompletion(settings.AOAIModel, settings.AOAIEndpoint, settings.AOAIKey)
                .Build();
            var companySearchPluginObj = new CompanySearchPlugin();
            var companySearchPlugin = kernel.ImportPluginFromObject(companySearchPluginObj, "CompanySearchPlugin");
            string currentDirectory = Directory.GetCurrentDirectory();
            var pluginDirectory = Path.Combine(currentDirectory, "plugins");
            var writetPlugin = kernel.ImportPluginFromPromptDirectory(Path.Combine(pluginDirectory, "WriterPlugin"));
            var emailPlugin = kernel.ImportPluginFromPromptDirectory(Path.Combine(pluginDirectory, "EmailPlugin"));
            var translatePlugin = kernel.ImportPluginFromPromptDirectory(Path.Combine(pluginDirectory, "TranslatePlugin"));
            string goal = "Check the weather in Guangzhou, use spanish to write emails abount dressing tips based on the results";

#pragma warning disable SKEXP0060

            var planner = new HandlebarsPlanner();
#pragma warning disable SKEXP0060

            var originalPlan = await planner.CreatePlanAsync(kernel, goal);
            Console.WriteLine(originalPlan);
            string v = originalPlan.ToString();
#pragma warning disable SKEXP0060
var originalPlanResult = await originalPlan.InvokeAsync(kernel, new KernelArguments());
            Console.WriteLine(originalPlanResult);
        }

        /// <summary>
        /// Qdrant测试
        /// </summary>
        /// <returns></returns>
        public async Task QdrantTest()
        {
            Settings settings = new Settings();
#pragma warning disable SKEXP0010 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
            var textEmbedding = new AzureOpenAITextEmbeddingGenerationService(settings.MTEmbeddingModel, settings.MTEndpoint, settings.MTKey);
#pragma warning restore SKEXP0010 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。


#pragma warning disable SKEXP0001 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
            var qdrantMemoryBuilder = new MemoryBuilder();
#pragma warning restore SKEXP0001 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
            qdrantMemoryBuilder.WithTextEmbeddingGeneration(textEmbedding);
#pragma warning disable SKEXP0001 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
#pragma warning disable SKEXP0020 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
            MemoryBuilder memoryBuilder = qdrantMemoryBuilder.WithQdrantMemoryStore("http://localhost:6333", 1536);
#pragma warning restore SKEXP0020 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。
#pragma warning restore SKEXP0001 // 类型仅用于评估，在将来的更新中可能会被更改或删除。取消此诊断以继续。

            var qdrantBuilder = qdrantMemoryBuilder.Build();

            await qdrantBuilder.SaveInformationAsync("conceptCollectionName", id: "info1", text: "Kinfey is Microsoft Cloud Advocate");
            await qdrantBuilder.SaveInformationAsync("conceptCollectionName", id: "info2", text: "Kinfey is ex-Microsoft MVP");
            await qdrantBuilder.SaveInformationAsync("conceptCollectionName", id: "info3", text: "Kinfey is AI Expert");
            await qdrantBuilder.SaveInformationAsync("conceptCollectionName", id: "info4", text: "OpenAI is a company that is developing artificial general intelligence (AGI) with widely distributed economic benefits.");

            string questionText = "Do you know kinfey ?";


            var searchResults = qdrantBuilder.SearchAsync("conceptCollectionName", questionText, limit: 3, minRelevanceScore: 0.7);


            await foreach (var item in searchResults)
            {
                Console.WriteLine(item.Metadata.Text + " : " + item.Relevance);
            }
        }
    }
}